package com.demo.netty.handlesort;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

public class DemoServer {
    public static void main(String[] args) {
        NioEventLoopGroup boss = new NioEventLoopGroup(1);
        NioEventLoopGroup worker = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss,worker)
                    .channel(NioServerSocketChannel.class)//设置了NioServerSocketChannel的工厂，用来反射生成NioServerSocketChannel的实例
                    .childHandler(new ChannelInitializer<SocketChannel>() {//设置了第一个InBoundHandler，负责添加用户的handler，设置成功会将自己移出
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new ServerInboundHandler());
                            ch.pipeline().addLast(new ServerInboundHandler2());
                            ch.pipeline().addLast(new ServerInboundHandler3());
                            ch.pipeline().addLast(new ServerOutboundHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture future = serverBootstrap.bind(8888).sync();//boss默认给了8*2个线程，这里只bind了一个端口，每次bind都会通过next()来获取
            // 一个NioEventLoop来执行select，如果绑定多余16个，就会从头再取。为了效率建议设置成2的整数倍，就可以使用PowerOf2Queue了
            ChannelFuture future2 = serverBootstrap.bind(8889).sync();
//            future.channel().closeFuture().sync();
            future.channel().closeFuture().addListeners(new GenericFutureListener<Future<? super Void>>() {
                @Override
                public void operationComplete(Future<? super Void> future) throws Exception {
                    System.out.println("NioServerSocketChannel-1 shutdown "+future.isSuccess());
                }
            });
            future2.channel().closeFuture().addListeners(new GenericFutureListener<Future<? super Void>>() {
                @Override
                public void operationComplete(Future<? super Void> future) throws Exception {
                    System.out.println("NioServerSocketChannel-2 shutdown "+future.isSuccess());
                }
            });
            future.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
